// Package middleware @author dingrui @since 2021/11/25
package middleware

import (
	"log"
	"os"
	"strings"
	"time"

	"github.com/kataras/golog"
	"github.com/kataras/iris/v12"
	"github.com/kataras/iris/v12/middleware/logger"

	"github.com/bannirui/mini-prize/common"
)

const (
	deleteFileOnExit = false             // 进程退出是否关闭当前日志文件
	// FIXME: 2021/11/26 openFile中只实现了文件不存在时创建文件 需要判断指定的目录不存在时也要创建
	dir              = "/Users/dingrui/logs/mini-prize/logs"            // 日志目录
	reqLogDir        = dir + "/request/" // 请求日志目录
	otherLogDir      = dir + "/other/"   // 其他日志墓库
	logFileSuffix    = ".log"            // 日志文件后缀
)

func InitLog() {
	var (
		err error
	)
	if err = os.MkdirAll(reqLogDir, os.ModePerm); err != nil {
		log.Fatal(err)
	}
	if err = os.MkdirAll(otherLogDir, os.ModePerm); err != nil {
		log.Fatal(err)
	}
	newOtherLogger()
	return
}

//
//  newLogFile
//  @Description: 打开一个文件
//  @param filename
//  @return *os.File
//
func openFile(filename string) *os.File {
	var (
		file *os.File
		err  error
	)
	// 打开一个输出文件，如果重新启动服务器，它将追加到今天的文件中
	if file, err = os.OpenFile(filename, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0666); err != nil {
		panic(err)
	}
	return file
}

//
//  NewRequestLogger
//  @Description: 打印请求日志
//  @return h
//  @return close
//
func NewRequestLogger() (h iris.Handler, close func() error) {
	var (
		err               error
		conf              logger.Config
		logFile           = openFile(reqLogDir + time.Now().Format(common.TimeFormatShort) + logFileSuffix)
		excludeExtensions = [...]string{
			".js",
			".css",
			".jpg",
			".png",
			".ico",
			".svg",
		}
	)

	close = func() error { return nil }
	conf = logger.Config{
		Status: true,
		IP:     true,
		Method: true,
		Path:   true,
	}

	close = func() error {
		err = logFile.Close()
		if deleteFileOnExit {
			err = os.Remove(logFile.Name())
		}
		return err
	}
	// 不想使用记录器，一些静态请求等
	conf.AddSkipper(func(ctx iris.Context) bool {
		var(
			path string
			ext string
		)
		path = ctx.Path()
		for _, ext = range excludeExtensions {
			if strings.HasSuffix(path, ext) {
				return true
			}
		}
		return false
	})
	h = logger.New(conf)
	return
}

//
//  newOtherLogger
//  @Description: 打印其他日志
//
func newOtherLogger() {
	var (
		logFile = openFile(otherLogDir + time.Now().Format(common.TimeFormatShort) + logFileSuffix)
	)
	golog.AddOutput(logFile)
}
